/**
 * @file TargetEvents.h
 * @brief 目标检测相关事件的定义
 */

#ifndef TARGETEVENTS_HPP
#define TARGETEVENTS_HPP


#include <opencv2/opencv.hpp>
#include "EventTypes.hpp"

namespace WaveGuard {

    /**
     * @class TargetEvent
     * @brief 目标检测事件的基类
     */
    class TargetEvent : public Event {
    public:
        TargetEvent(EventType type, int targetId, const std::string &source = "TargetDetector")
            : Event(type, source), m_targetId(targetId) {
        }

        /**
         * @brief 获取目标ID
         * @return 目标ID
         */
        int getTargetId() const { return m_targetId; }

        std::string toString() const override {
            return Event::toString() + ", targetId=" + std::to_string(m_targetId);
        }

    protected:
        int m_targetId; // 目标ID
    };

    /**
     * @class TargetDetectedEvent
     * @brief 检测到新目标事件
     */
    class TargetDetectedEvent : public TargetEvent {
    public:
        TargetDetectedEvent(int targetId, const cv::Rect &boundingBox, float confidence,
            const std::string &className, const std::string &source = "TargetDetector")
            : TargetEvent(EventType::TARGET_DETECTED, targetId, source),
            m_boundingBox(boundingBox), m_confidence(confidence), m_className(className) {
        }

        /**
         * @brief 获取目标边界框
         * @return 目标边界框
         */
        cv::Rect getBoundingBox() const { return m_boundingBox; }

        /**
         * @brief 获取检测置信度
         * @return 置信度
         */
        float getConfidence() const { return m_confidence; }

        /**
         * @brief 获取目标类别
         * @return 目标类别名称
         */
        std::string getClassName() const { return m_className; }

        std::string toString() const override {
            return TargetEvent::toString() + ", bbox=[" +
                std::to_string(m_boundingBox.x) + "," +
                std::to_string(m_boundingBox.y) + "," +
                std::to_string(m_boundingBox.width) + "," +
                std::to_string(m_boundingBox.height) + "], confidence=" +
                std::to_string(m_confidence) + ", class=" + m_className;
        }

    private:
        cv::Rect m_boundingBox;  // 目标边界框
        float m_confidence;      // 检测置信度
        std::string m_className; // 目标类别
    };

    /**
     * @class TargetRangeEvent
     * @brief 目标进入/离开射程事件的基类
     */
    class TargetRangeEvent : public TargetEvent {
    public:
        TargetRangeEvent(EventType type, int targetId, float distance,
            const std::string &source = "TargetDetector")
            : TargetEvent(type, targetId, source), m_distance(distance) {
        }

        /**
         * @brief 获取目标距离
         * @return 目标距离
         */
        float getDistance() const { return m_distance; }

        std::string toString() const override {
            return TargetEvent::toString() + ", distance=" + std::to_string(m_distance);
        }

    protected:
        float m_distance; // 目标距离
    };

    /**
     * @class TargetInRangeEvent
     * @brief 目标进入射程事件
     */
    class TargetInRangeEvent : public TargetRangeEvent {
    public:
        TargetInRangeEvent(int targetId, float distance,
            const std::string &source = "TargetDetector")
            : TargetRangeEvent(EventType::TARGET_IN_RANGE, targetId, distance, source) {
        }
    };

    /**
     * @class TargetOutOfRangeEvent
     * @brief 目标离开射程事件
     */
    class TargetOutOfRangeEvent : public TargetRangeEvent {
    public:
        TargetOutOfRangeEvent(int targetId, float distance,
            const std::string &source = "TargetDetector")
            : TargetRangeEvent(EventType::TARGET_OUT_OF_RANGE, targetId, distance, source) {
        }
    };

    /**
     * @class TargetLostEvent
     * @brief 丢失目标事件
     */
    class TargetLostEvent : public TargetEvent {
    public:
        TargetLostEvent(int targetId, const std::string &source = "TargetTracker")
            : TargetEvent(EventType::TARGET_LOST, targetId, source) {
        }
    };

} // namespace WaveGuard
#endif // !TARGETEVENTS_HPP
